from taichu_storage import Protocol, create_storage, StorageInterface
from taichu_storage.boto3_client import StorageBoto3

from myapp.utils.region import get_regions_info
import retry

class StorageMgrFactory:
    _instances = {}

    @staticmethod
    def region(region_key):

        if region_key in StorageMgrFactory._instances:
            print(f"Using cached StorageManager for region: {region_key}")
            return StorageMgrFactory._instances[region_key]

        regions = get_regions_info()

        region = next((r for r in regions if r['key'] == region_key), None)

        if region:
            s3_config = region['s3']
            manager = RegionStorageManager(s3_config)
            StorageMgrFactory._instances[region_key] = manager
            return manager
        else:
            raise ValueError(f"Region with key '{region_key}' not found")


class RegionStorageManager(StorageInterface):
    def __init__(self, s3_config):
        print(s3_config['ak'])
        print(s3_config['sk'])
        print(s3_config['endpoint'])
        print(s3_config['external_endpoint'])
        cfgs = {
            'ak': s3_config['ak'],
            'sk': s3_config['sk'],
            'endpoint_url': s3_config['endpoint'],
            'bucket': 'publish-data',
            'endpoint_url_external': s3_config['external_endpoint'],
        }
        # self.cli = create_storage(Protocol.BOTO3, cfgs)
        self.cli = StorageBoto3(cfgs)

    @retry.retry(tries=5, delay=0.2)
    def list_objects(self, key, delimiter=''):
        return self.cli.list_objects(key, delimiter)

    @retry.retry(tries=5, delay=0.2)
    def get_object(self, key):
        return self.cli.get_object(key)

    @retry.retry(tries=5, delay=0.2)
    def put_object(self, key, content):
        return self.cli.put_object(key, content)

    @retry.retry(tries=5, delay=0.2)
    def upload_file(self, local_filename, key):
        return self.cli.upload_file(local_filename, key)

    @retry.retry(tries=5, delay=0.2)
    def upload_dir(self, local_dir, key):
        return self.cli.upload_dir(local_dir, key)

    @retry.retry(tries=5, delay=0.2)
    def download_file(self, key, local_filename):
        return self.cli.download_file(key, local_filename)

    @retry.retry(tries=5, delay=0.2)
    def download_dir(self, key, local_dir):
        return self.cli.download_dir(key, local_dir)

    @retry.retry(tries=5, delay=0.2)
    def copy_object(self, source_key, target_key):
        return self.cli.copy_object(source_key, target_key)

    @retry.retry(tries=5, delay=0.2)
    def copy_dir(self, source_dir, dest_dir):
        return self.cli.copy_dir(source_dir, dest_dir)

    @retry.retry(tries=5, delay=0.2)
    def create_dir(self, dirname):
        return self.cli.create_dir(dirname)

    @retry.retry(tries=5, delay=0.2)
    def generate_signed_url(self, key, expiration=3600, use_external_host=True, content_type=None):
        return self.cli.generate_signed_url(key, expiration, use_external_host, content_type)

    @retry.retry(tries=5, delay=0.2)
    def generate_upload_credentials(self, key, expiration=3600, use_external_host=True):
        return self.cli.generate_upload_credentials(key, expiration, use_external_host)
